package spoon.sbobet.service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import spoon.common.exception.ConvertException;
import spoon.sbobet.dao.SbobetDao;
import spoon.sbobet.domain.GameLink;
import spoon.service.HttpService;

@Transactional
public abstract class SbobetServiceImpl implements SbobetService {
	
	@Autowired
	protected HttpService httpService;
	
	@Autowired
	protected SbobetDao sbobetDao;

	protected Logger log = LoggerFactory.getLogger(this.getClass());
	
	protected static String linkPattern = "[1-9]{1},[0-9]+,\\[[0-9]+,'[^']+','[^']+','[0-9.]+',[0-9]+,'[^']+'";

	protected static String dataPattern = "\\[[0-9]+,\\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[-0-9.]+,[0-9]+\\],\\[[0-9.,]+\\]";
	
	protected String dynamicScript = "";
	
	protected String leagueData = "";
	
	protected String nationalData = "";
	
	@Override
	public abstract List<GameLink> getLink();
		
	@Override
	public abstract void getGame(GameLink gameLink);
	
	/**
	 * 링크정보로 dynimic script 에서 정보를 가져온다.
	 * 
	 * @param gameLink
	 * @param link
	 */
	protected void getLinkInfo(GameLink gameLink, String link) {

		String[] links = link.split(",");
		String dynimicData = "";
		
		Pattern p = Pattern.compile("\\[" + links[1] + ",'[^']+',[0-9]+,[0-9]+");
		Matcher m  = p.matcher(dynamicScript);
		
		while (m.find()) {
			dynimicData = m.group();
		}
		
		String[] data = dynimicData.split(",");
		gameLink.setGameId(links[2].substring(1));
		gameLink.setLeague(getLeague(links[1]));
		gameLink.setNational(getNational(data[3]));
		gameLink.setHomeTeam(getStringData(links[3]));
		gameLink.setAwayTeam(getStringData(links[4]));
		gameLink.setGameDate(convertDate(getStringData(links[7])));
		convertLink(gameLink);
	}

	/**
	 * 문자열에서 ' 를 제외한 문자열만 가져온다.
	 * 
	 * @param league
	 * @return
	 */
	protected String getStringData(String league) {
		return league.substring(league.indexOf("'") + 1, league.lastIndexOf("'"));
	}
	
	/**
	 * 국가정보와 리그정보 분리
	 */
	protected void addDynamicData() {
		String[] datas = dynamicScript.split("\\$");
		for (int i = 0; i < datas.length; i++) {
			if (datas[i].contains("'regions'")) {
				nationalData = datas[i];
			} else if (datas[i].contains("'tournaments'")) {
				leagueData = datas[i];
			}
		}
	}
	
	/**
	 * key값으로 국가정보를 가져온다.
	 * 
	 * @param key
	 * @return
	 */
	protected String getNational(String key) {
		
		Pattern p = Pattern.compile("\\[" + key + ",'[^']+'");
		Matcher m  = p.matcher(nationalData);
		String national = "";
		
		if (m.find()) {
			national = getStringData(m.group());
		}
		
		return national;
	}
	
	/***
	 * key값으로 리그정보를 가져온다.
	 * 
	 * @param key
	 * @return
	 */
	protected String getLeague(String key) {
		Pattern p = Pattern.compile("\\[" + key + ",'[^']+'");
		Matcher m  = p.matcher(leagueData);
		String league = "";
		
		if (m.find()) {
			league = getStringData(m.group());
		}
		
		return league;
	}
	
	/**
	 * 날짤 변환 표준시간으로
	 * 
	 * @param dt
	 * @return
	 */
	protected Date convertDate(String dt) {
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:ss");
		TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); // 중국시간 +8
		df.setTimeZone(tz);

		Date date = new Date();
		try {
			date = df.parse(dt);
		} catch (ParseException e) {
			throw new ConvertException(new Throwable("Sbobet - 날짜변경 에러 (" + dt + ")" , e));
		}
		return date;
	}
	
	/**
	 * 링크정보를 넘겨줌 https://www.sbobet.com/리그/아이디/홈팀-vs-원정팀
	 * 
	 * @param gameLink
	 */
	protected void convertLink(GameLink gameLink) {
		String link = gameLink.getDomain() + "/" + gameLink.getLeague().toLowerCase().replace(" ", "-")
				+ "/" + gameLink.getGameId() + "/" + gameLink.getHomeTeam().toLowerCase().replace(" ", "-")
				+ "-vs-" + gameLink.getAwayTeam().toLowerCase().replace(" ", "-");
		gameLink.setLink(link);
	}
	
	/**
	 * 핸디캡을 문자열로 +, - 붙여서 보여준다.
	 * 
	 * @param handi
	 * @return
	 */
	protected String getHandi(Double handi) {
		String d = "";
		
		if (handi == 0D) {
			d = "0";
		} else if (handi > 0) {
			d ="+" + handi;
		} else {
			d = "-" + (handi * -1);
		}
		
		return d;
	}
	
	/**
	 * 디비 입력
	 * 
	 * @param gameLink
	 * @return
	 */
	protected Integer addBetting(GameLink gameLink) {
		sbobetDao.delete(gameLink);
		return sbobetDao.addBetting(gameLink);
	}

}
